package com.leetcode;

/**
 * 529. 扫雷游戏
 *
 * @author fy
 * @date 2022/3/28 14:54
 */
public class Solution529 {

    private int m, n;
    private final char B = 'B';
    private final char E = 'E';
    private final char M = 'M';
    private final char X = 'X';
    //private final int[][] d = new int[][]{{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
    private final int[][] boomD = new int[][]{{-1, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, -1}, {1, 1}, {-1, 1}, {1, -1}};
    private boolean[][] visited;

    public char[][] updateBoard(char[][] board, int[] click) {
        if (board == null || click == null) {
            return board;
        }
        if (board.length == 0) {
            return board;
        }
        if (click.length < 2) {
            return board;
        }

        this.m = board.length;
        this.n = board[0].length;

        int x = click[0];
        int y = click[1];

        if (!inArea(x, y)) {
            throw new RuntimeException("click not in board");
        }

        this.visited = new boolean[this.m][this.n];
        for (int i = 0; i < this.m; i++) {
            for (int j = 0; j < this.n; j++) {
                this.visited[i][j] = false;
            }
        }

        char clickChar = board[x][y];
        if (clickChar == B || clickChar == X) {
            return board;
        }
        // 点击炸弹改为X
        if (clickChar == M) {
            board[x][y] = X;
            return board;
        }
        if (clickChar == E) {
            changeBoard(board, x, y);
        }
        // 其他点击数字的情况也直接返回
        return board;
    }

    private boolean inArea(int x, int y) {
        return x >= 0 && x < this.m && y >= 0 && y < this.n;
    }

    private void changeBoard(char[][] board, int x, int y) {
        System.out.println(String.format("x: %s, y: %s", x, y));
        this.visited[x][y] = true;
        int count = this.boomCount(board, x, y);
        if (count > 0) {
            char c = (char) (count + '0');
            board[x][y] = c;
            return;
        }
        if (count == 0) {
            board[x][y] = B;
            for (int i = 0; i < this.boomD.length; i++) {
                int newX = x + boomD[i][0];
                int newY = y + boomD[i][1];
                if (this.inArea(newX, newY) && !this.visited[newX][newY] && board[newX][newY] == E) {
                    changeBoard(board, newX, newY);
                }
            }
        }
    }

    private int boomCount(char[][] board, int x, int y) {
        int count = 0;
        for (int i = 0; i < this.boomD.length; i++) {
            int newX = x + boomD[i][0];
            int newY = y + boomD[i][1];
            if (this.inArea(newX, newY) &&
                    (board[newX][newY] == M || board[newX][newY] == X)) {
                count++;
            }
        }
        return count;
    }

    public static void main(String[] args) {
        char[][] board = new char[][]{
                {'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E'},
                {'E', 'E', 'E', 'E', 'E', 'E', 'E', 'M'},
                {'E', 'E', 'M', 'E', 'E', 'E', 'E', 'E'},
                {'M', 'E', 'E', 'E', 'E', 'E', 'E', 'E'},
                {'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E'},
                {'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E'},
                {'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E'},
                {'E', 'E', 'M', 'M', 'E', 'E', 'E', 'E'}
        };
        new Solution529().updateBoard(board, new int[]{0, 0});
    }
}
